<template>
  <div :key="item.id" v-for="item in children" :class="item.props?.class">
    <component
      v-if="!item.props?.Options"
      :is="item.type"
      @click="handleClick(item.actions)"
      v-bind="item.props"
      @update:modelValue="(val) => updateModelValue(item, val)"
      :key="item.id"
      @update:checked="(flag) => updateChecked(item, flag)"
      :disabled="item.props.disabled"
    >
    </component>
    <component
      v-else
      :is="item.type"
      :key="item.id"
      @click="handleClick(item.actions)"
      :Options="item.props.Options"
      :defaultValue="item.props.defaultValue"
      @update:modelValue="handleChangInput"
      @update:open="
        (val) => {
          handelSelectRefenceVaule(val, item.id)
        }
      "
      :disabled="item.props.disabled"
    >
    </component>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watchEffect, markRaw, PropType } from 'vue'
import storeMap from '@/pina/index'
import { useNode, useVueFlow } from '@vue-flow/core'
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@/components/ui/collapsible'
import { ChevronsUpDownIcon, ChevronDown, ChevronUp, PlusIcon, AlertCircleIcon, MinusCircleIcon } from 'lucide-vue-next'
import { Textarea } from '@/components/ui/textarea'
import { Label } from '@/components/ui/label'
import { Input } from '@/components/ui/input'
import { Switch } from '@/components/ui/switch'
import { Button } from '@/components/ui/button'
// import SelectComponent from '@/components/vue-flow/nodes/selectComponent.vue'
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
  SelectItemText
} from '@/components/ui/select'

interface Item {
  id: string
  type: any
  props: ItemProps
  actions?: any[]
  Options: []
  children?: ItemProps[]
}
interface ItemProps {
  class?: string
  Options?: any
  modelValue?: any
  defaultValue?: any
  actions?: string
  disabled?: boolean
}

interface Option {
  label: string
  value: string
}

interface OutputItem {
  name: string
}

interface NodeData {
  title?: string
  label?: string
  output?: OutputItem[]
}

interface Node {
  id: string
  data: NodeData
}

interface Edge {
  source: string
  target: string
}

interface ReferenceOption {
  groupName: string
  options: Option[]
}
export default defineComponent({
  props: {
    children: {
      type: Array as PropType<
        {
          id: string
          type: any
          label: string
          props: { class?: string | object; Options?: Option[]; defaultValue?: string }
          actions: string
        }[]
      >
    },
    id: String,
    props: Object,
    stroeId: String,
    priorityIndex: Number,
    disabled: Boolean
  },
  components: {
    Collapsible,
    CollapsibleTrigger,
    CollapsibleContent,
    ChevronsUpDownIcon,
    ChevronDown,
    ChevronUp,
    PlusIcon,
    AlertCircleIcon,
    MinusCircleIcon,
    Textarea,
    Label,
    Input,
    Switch,
    Button,
    Select,
    SelectContent,
    SelectGroup,
    SelectItem,
    SelectTrigger,
    SelectValue,
    SelectItemText,
    // SelectComponent
  },
  setup(props) {
    // const data = ref([])
    const referenceOptions = ref<ReferenceOption[]>([])
    const prevNodeId = ref<string | undefined>()
    const node = useNode()
    const { findNode } = useVueFlow()
    const { stroeId, disabled = false } = props

    const handleClick = (actions: string) => {
      if (actions?.length) {
        for (let i = 0; i < actions.length; i++) {
          const element = actions[i]
          if (stroeId === 'useIfStore') {
            storeMap[stroeId]()[element](props.id, props.priorityIndex)
          } else {
            storeMap[stroeId]()[element](props.id)
          }
        }
      }
    }

    const handelSelectRefenceVaule = (flag: boolean, id: string) => {
      console.log(stroeId,flag,id)
      if (stroeId !== 'LLMOutPutStore' && stroeId !== 'useStartStore') {
        selectRefrenceVaule(flag, id)
      }
    }

    const handleChangInput = (val: string) => {
      if (stroeId !== 'LLMOutPutStore' && stroeId !== 'useStartStore') {
        changeSelectType(val)
      }
    }

    const selectRefrenceVaule = (flag: string | boolean, id: string) => {
      if (typeof flag == 'boolean') {
        if (stroeId && storeMap.Property(stroeId)) {
          storeMap[stroeId]().setOptions(referenceOptions, prevNodeId, id)
        }
      }
    }

    const changeSelectType = (val: string) => {
      if (typeof val !== 'boolean') {
        if (stroeId && storeMap.hasOwnProperty(stroeId)) {
          storeMap[stroeId]().changeInput(val, props.id, referenceOptions, prevNodeId, props.priorityIndex)
        }
      }
    }

    const updateModelValue = (item: Item, val: string) => {
      item.props.modelValue = val
    }

    const updateChecked = (item: Item, flag: boolean) => {
      item.props.modelValue = flag
    }

    watchEffect(() => {
      if (node.connectedEdges && node.connectedEdges.value.length > 0) {
        const filteredEdges = node.connectedEdges.value.filter((item: Edge) => item.target === node.id)
        referenceOptions.value = filteredEdges.map((edge: Edge) => {
          const sourceNode = findNode(edge.source) as Node | undefined
          if (!sourceNode) {
            return { groupName: '', options: [] }
          }

          prevNodeId.value = sourceNode.id
          const currentItem: ReferenceOption = {
            groupName: sourceNode.data.title ?? sourceNode.data.label ?? '',
            options: []
          }

          if (sourceNode.data.output) {
            sourceNode.data.output
              .filter((item: OutputItem) => Boolean(item.name))
              .forEach((option: OutputItem) => {
                const optionsObj: Option = {
                  label: option.name,
                  value: option.name
                }
                currentItem.options.push(optionsObj)
              })
          } else {
            currentItem.options = []
          }

          return currentItem
        })
      }
    })

    return {
      handleClick,
      handelSelectRefenceVaule,
      handleChangInput,
      updateModelValue,
      updateChecked,
      referenceOptions,
      markRaw,
      disabled
    }
  }
})
</script>

<style lang="scss">
.no-gap-radius-left {
  button {
    margin-left: -7px;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-left: 0;
  }

  input {
    margin-left: -7px;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-left: 0;
  }
}

.no-gap-radius-right {
  button {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }
}

.icon-self-center {
  align-self: center;
}
</style>
